#!/usr/bin/env python
# coding: utf-8
"""
#python system_mac_config.py --set "enable" --check "enable"    #query all mac, log unexpexted mac, and set system mac with inventory mac.
#python system_mac_config.py --set "enable" --check "disable"   #query all mac, and set system mac with inventory mac.
#python system_mac_config.py --set "disable" --check "enable"   #query all mac, and log unexpected mac.
#python system_mac_config.py --set "disable" --check "disable"  #query all mac.
"""

import re
import os
import time
import datetime
import string
from onshs.ne.tnxxx.tnxxxcfg_basecase import *

log_node_prefix             = "sync_check"
log_node_summary            = log_node_prefix+r"_summary"
log_node_fail               = log_node_prefix+r"_fail"
log_node_success            = log_node_prefix+r"_success"
log_node_warning            = log_node_prefix+r"_warning"

log_file_notexisted_fail    = "the file:%s isn't existed\n"
log_master_opca_fail        = "get ip:%s master opca is failed\n"
log_opca_slotlist_fail      = "get ip:%s opca slot list is failed\n"
log_connect_fail            = "connect ip:%s failed\n"
log_checkhw_fail            = "ip:%s slot:%s checkhw failed\n"
log_checkhw_lsp_fail        = "ip:%s slot:%s checkhw lsp failed\n"
log_checkhw_pw_fail         = "ip:%s slot:%s checkhw pw failed\n"
log_checkhw_ethpw_fail      = "ip:%s slot:%s checkhw ethpw failed\n"
log_check_linkstatus_fail   = "ip:%s unit:%s port:%s linkstatus is not synced\n"
log_check_phystatus_fail    = "ip:%s unit:%s port:%s phystatus is not synced\n"

log_one_opca_success        = "ip:%s only have one opca card, need not do sync check\n"
log_master_opca_success     = "ip:%s master opca is %d\n"
log_checkhw_success         = "ip:%s slot:%s checkhw success\n"
log_checkhw_lsp_success     = "ip:%s slot:%s checkhw lsp success\n"
log_checkhw_pw_success      = "ip:%s slot:%s checkhw pw success\n"
log_checkhw_ethpw_success   = "ip:%s slot:%s checkhw ethpw success\n"
log_check_linkstatus_success= "ip:%s linkstatus is synced\n"
log_check_phystatus_success = "ip:%s phystatus is synced\n"

log_summary_success         = "ip:%s sync check success"
log_summary_fail            = "ip:%s sync check failed"


class TestCase(TnxxxCfg_BaseCase):
    """
    TestCase
    """
    OPTIONS = [
        {
            'opt' : '--cfgfile',
            'dest': 'cfgfile',
            'metavar' : 'CFGFILE',
            'help' : 'the file of ip list configuration',
            'required' : False,
            'default' : "ip.txt"
        },
        {
            'opt' : '--set',
            'dest': 'set',
            'metavar' : 'SET',
            'help' : 'the configuration of set system mac',
            'required' : False,
            'default' : "enable"
        },        
    ]     
    
    def info_init(self):
        self.info_dic = {}     
              
        return True 
    
    #以node???字，把信息保存到info_dic[node]中。
    def info_show(self, node, info):
        node = self.set + r'_' + node
        if not self.info_dic.has_key(node):
            self.info_dic[node] = ""
        self.info_dic[node] += info + '\n'        
        return True    
            
    def info_file_save(self, ip):
        path = os.getcwd()+'/LOG'+'//'
        
        for node in self.info_dic:
            info_list = open(path+node+'_'+self.worktime+'.txt','a')            
            info_list.write(self.info_dic[node])
            info_list.close()
            
        return True
    
    def get_iplist(self):
        iplist_filted = []                
        if os.path.isfile(os.getcwd()+r'/'+ self.iplistfile):
            iplist = open(os.getcwd()+r'/'+ self.iplistfile)            
        else:
            self.info_show(log_node_fail, log_file_notexisted_fail%(self.iplistfile))            
            return iplist_filted 
        
        for line in iplist:
            if re.match(r'^\s*$', line) is not None : continue # 忽略空白行
            if re.match(r'^\s*#', line) is not None : continue # 忽略注?行            
            iplist_filted.append(line.strip('\n'))        
            
        iplist.close()
        
        return iplist_filted
    
    #?找指定槽位列表的?板?型是否存在
    def get_slot_cardtype_list(self, slot_list,card_type):
        rtn = None
        rtn = self.tnxxx.send_rtn_str("show card", self.get_ne_ip(0), 0, CLI_PORT)
        card_info_list = re.findall(r"slot:\s+(\d+)\s+(?:--More--\s+)?stat:\s+\w+\s+(?:--More--\s+)?Card:\s+(\w+)\s+", rtn, re.I)
        slot_cardtype_list = []
        for card_info in card_info_list:
            slot = int(card_info[0])
            if slot not in slot_list:
                continue
            
            card_name = card_info[1].upper()
            if card_name != card_type:
                continue
            
            slot_cardtype_list.append(slot)
            
        return slot_cardtype_list
        
    def get_master_opca(self):
        query_masterppc_cmd = '''$.dbgcli.0.Cmd "queryasyn valid 1, NeStat, (MasterPPC), *"'''
        rtn_str = None        
        rtn_str = self.tnxxx.send_rtn_str(query_masterppc_cmd, self.get_ne_ip(0), 0, MTN_PORT)
        if [] == re.findall('success', rtn_str) or [] == re.findall('\d',rtn_str):         
            self.info_show(log_node_fail, log_master_opca_fail%(self.get_ne_ip(0)))
            self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))
            return False
        else:            
            self.master_opca = int(re.findall('\d',rtn_str)[0])
            self.slave_opca = 7 - self.master_opca
            self.info_show(log_node_success, log_master_opca_success%(self.get_ne_ip(0),self.master_opca))           
            return True 
    
    def check_hw(self):
        query_cmd_list = [['$.card.%d.mtn.0.cmds "checkhw"'%(self.master_opca),self.master_opca],['$.card.%d.mtn.0.cmds "checkhw"'%(self.slave_opca),self.slave_opca]]
        
        for query_cmd in query_cmd_list:
            rtn_str = None       
            rtn_str = self.tnxxx.send_rtn_str(query_cmd[0], self.get_ne_ip(0), query_cmd[1], MTN_PORT)
            if [] == re.findall('success', rtn_str):         
                self.info_show(log_node_fail, log_checkhw_fail%(self.get_ne_ip(0),query_cmd[1]))
                self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))            
                return False
            elif [] == re.findall('lsp hw data is ok', rtn_str):
                self.info_show(log_node_fail, log_checkhw_lsp_fail%(self.get_ne_ip(0),query_cmd[1]))
                self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))            
                return False
            elif [] == re.findall('pw hw data is ok', rtn_str):
                self.info_show(log_node_fail, log_checkhw_pw_fail%(self.get_ne_ip(0),query_cmd[1]))
                self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))            
                return False
            elif [] == re.findall('eth pw hw data is ok', rtn_str):
                self.info_show(log_node_fail, log_checkhw_ethpw_fail%(self.get_ne_ip(0),query_cmd[1]))
                self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))            
                return False
            else:
                self.info_show(log_node_success, log_checkhw_success%(self.get_ne_ip(0),query_cmd[1]))
            
        return True
    
    def check_unit_port_link(self):
        cmd_list = [['dbg_if_print',self.master_opca],['dbg_if_print',self.slave_opca]]
        
        opca_linkup_portlist = [] 
        for cmd in cmd_list:
            rtn_str = None
            linkup_port_list = []
            rtn_str = self.tnxxx.send_rtn_str(cmd[0], self.get_ne_ip(0), cmd[1], DEV_PORT)            
            linkup_port_list = re.findall(r"\s+(\d+)\s+(\d+)\s+(\w+)\(up\/up\)", rtn_str)
            opca_linkup_portlist.append(linkup_port_list)
        
        if len(opca_linkup_portlist[0]) != len(opca_linkup_portlist[1]):
            self.info_show(log_node_fail, log_check_linkstatus_fail%(self.get_ne_ip(0),"all","all"))
            self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))
            return False
        
        #linkup_port_list = [[unit,port,ge0],[unit,port,ge1],...]   
        for i in range(0,len(opca_linkup_portlist[0])):
            if opca_linkup_portlist[0][i][0] == opca_linkup_portlist[1][i][0] and opca_linkup_portlist[0][i][1] == opca_linkup_portlist[1][i][1] and opca_linkup_portlist[0][i][2] == opca_linkup_portlist[1][i][2]:                
                continue
            else:
                self.info_show(log_node_fail, log_check_linkstatus_fail%(self.get_ne_ip(0),opca_linkup_portlist[0][i][0],opca_linkup_portlist[0][i][1]))
                self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))
                return False
        self.linkup_portlist = opca_linkup_portlist[0]
        self.info_show(log_node_success, log_check_linkstatus_success%(self.get_ne_ip(0)))    
           
        return True
    
    def check_phy_status(self):
        cmd_list = [['dbg_print_master_phy_stat',self.master_opca],['dbg_print_slave_phy_stat',self.slave_opca]]
        
        for element in self.linkup_portlist:
            opca_phy_status_list = []
            for cmd in cmd_list:
                rtn_str = None
                phy_status_list = []
                
                rtn_str = self.tnxxx.send_rtn_str(cmd[0]+r' '+element[0]+r','+element[1], self.get_ne_ip(0), cmd[1], DEV_PORT)            
                phy_status_list = re.findall(r"\s+(\w+)\s+:\s+(\d+)", rtn_str)
                opca_phy_status_list.append(phy_status_list)
            
            if len(opca_phy_status_list[0]) != len(opca_phy_status_list[1]):
                self.info_show(log_node_fail, log_check_phystatus_fail%(self.get_ne_ip(0),"all","all"))
                self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))
                return False 
                
            for i in range(0,len(opca_phy_status_list[0])):
                if opca_phy_status_list[0][i][0] == opca_phy_status_list[1][i][0] and opca_phy_status_list[0][i][1] == opca_phy_status_list[1][i][1]:
                    continue
                else:
                    self.info_show(log_node_fail, log_check_phystatus_fail%(self.get_ne_ip(0),element[0],element[1]))
                    self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))
                    return False
        
        self.info_show(log_node_success, log_check_phystatus_success%(self.get_ne_ip(0)))      
        return True            
                   
            
    def _execute(self):                        
        self.info_init()
        
        worktime = str(datetime.datetime.now())
        self.worktime = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        
        self.iplistfile = self.options.cfgfile
        self.set = self.options.set       
        self.work_path = os.getcwd()
        
        ip_list = self.get_iplist()         
        
        for ip in ip_list:            
            self.set_ne_ip(0, ip)  
            self.master_opca = 0
            self.slave_opca = 0
            self.linkup_portlist = []
            self.tnxxx.disconnect()
            
            slot_list = self.get_slot_cardtype_list([3,4],"OPCA")
            if len(slot_list) == 0:
                self.info_show(log_node_fail, log_opca_slotlist_fail%(self.get_ne_ip(0)))
                self.info_show(log_node_summary, log_summary_fail%(self.get_ne_ip(0)))
                continue               
            elif len(slot_list) == 1:
                self.info_show(log_node_success, log_one_opca_success%(self.get_ne_ip(0)))
                self.info_show(log_node_summary, log_summary_success%(self.get_ne_ip(0)))
                continue  
            
            if False == self.get_master_opca():
                continue
            
            if False == self.check_hw():
                continue
            
            if False == self.check_unit_port_link():
                continue
            
            if False == self.check_phy_status():
                continue
                            
            self.info_show(log_node_summary, log_summary_success%(ip))
            print "ip:%s opca configuration is synchronized, you can do cfp switch now"%(self.get_ne_ip(0))
           
        worktime = str(datetime.datetime.now())
        self.worktime_end = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        
        self.info_show(log_node_summary, "The system mac operation begin time %s "%(self.worktime))
        self.info_show(log_node_summary, "The system mac operation end time %s "%(self.worktime_end))
        
        ip = '0.0.0.0'
        self.info_file_save(ip)        
        return True
    
if __name__ == "__main__" :
    case = TestCase()
    case.execute()


